from flask import Flask, render_template, send_from_directory, request, jsonify
from database import get_all_records, init_db, save_records as db_save_records, get_record_by_id, delete_record, get_all_processed_videos, update_record_favorite, update_record_path
from config import BASE_DIR, PREVIEW_SAVE_DIR, VIDEO_SOURCE_DIR, FAVORITE_DIR, PER_PAGE
from video_processor import process_video
import os
import shutil
import hashlib
import threading
import time

app = Flask(__name__)

# 添加basename过滤器
@app.template_filter('basename')
def basename_filter(path):
    """获取文件路径的基本名称"""
    return os.path.basename(path)

@app.route("/")
def index():
    # 获取当前页码，默认为1
    page = request.args.get('page', 1, type=int)
    # 获取每页数量，优先URL参数，否则用配置
    per_page = request.args.get('per_page', PER_PAGE, type=int)
    # 获取当前标签页
    tab = request.args.get('tab', 'all')
    # 获取排序参数
    sort_by = request.args.get('sort_by', 'id')
    sort_order = request.args.get('sort_order', 'asc')
    
    # 获取所有记录
    all_records = get_all_records()
    
    # 统计文件数量
    total_files = len(all_records)
    favorite_files = len([r for r in all_records if r.get('is_favorite')])
    normal_files = total_files - favorite_files
    
    # 根据标签页筛选记录
    if tab == 'favorites':
        filtered_records = [r for r in all_records if r.get('is_favorite')]
    else:
        filtered_records = [r for r in all_records if not r.get('is_favorite')]
    
    # 排序处理
    def get_sort_key(record):
        if sort_by == 'id':
            return record['id']
        elif sort_by == 'duration':
            return record.get('duration', 0) or 0
        elif sort_by == 'path':
            return os.path.basename(record['original']).lower()
        return record['id']
    
    # 应用排序
    filtered_records.sort(key=get_sort_key, reverse=(sort_order == 'desc'))
    
    # 计算总页数
    total_pages = (len(filtered_records) + per_page - 1) // per_page
    
    # 获取当前页的记录
    start_idx = (page - 1) * per_page
    end_idx = start_idx + per_page
    current_page_records = filtered_records[start_idx:end_idx]
    
    return render_template("index.html", 
                         records=current_page_records,
                         current_page=page,
                         total_pages=total_pages,
                         per_page=per_page,
                         current_tab=tab,
                         total_files=total_files,
                         favorite_files=favorite_files,
                         normal_files=normal_files,
                         sort_by=sort_by,
                         sort_order=sort_order)

@app.route("/preview/<path:filename>")
def preview_file(filename):
    """提供预览文件下载/播放"""
    return send_from_directory(PREVIEW_SAVE_DIR, filename)

@app.route("/video/<int:record_id>")
def video_file(record_id):
    """提供视频文件下载/播放"""
    record = get_record_by_id(record_id)
    if record and os.path.exists(record['original']):
        return send_from_directory(
            os.path.dirname(record['original']), 
            os.path.basename(record['original'])
        )
    return "视频不存在", 404

@app.route("/play/<int:record_id>")
def play_video(record_id):
    """视频播放页面"""
    record = get_record_by_id(record_id)
    if record and os.path.exists(record['original']):
        # 获取来源页参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 12, type=int)
        return render_template("play.html", record=record, page=page, per_page=per_page)
    return "视频不存在", 404

@app.route("/delete/<int:record_id>", methods=['POST'])
def delete_video(record_id):
    """删除视频文件"""
    try:
        record = get_record_by_id(record_id)
        if not record:
            return jsonify({"success": False, "message": "视频不存在"})

        # 删除原始视频文件
        video_path = record['original']
        print(f"尝试删除视频文件: {video_path}")
        if os.path.exists(video_path):
            try:
                os.remove(video_path)
                print(f"成功删除视频文件: {video_path}")
            except Exception as e:
                print(f"删除视频文件失败: {e}")
                return jsonify({"success": False, "message": f"删除视频文件失败: {str(e)}"})
        else:
            print(f"视频文件不存在: {video_path}")

        # 删除预览文件（可能是列表）
        preview_paths = record['preview']
        if isinstance(preview_paths, list):
            for preview_path in preview_paths:
                print(f"尝试删除预览文件: {preview_path}")
                if os.path.exists(preview_path):
                    try:
                        os.remove(preview_path)
                        print(f"成功删除预览文件: {preview_path}")
                    except Exception as e:
                        print(f"删除预览文件失败: {e}")
                else:
                    print(f"预览文件不存在: {preview_path}")
        elif os.path.exists(preview_paths):
            print(f"尝试删除预览文件: {preview_paths}")
            try:
                os.remove(preview_paths)
                print(f"成功删除预览文件: {preview_paths}")
            except Exception as e:
                print(f"删除预览文件失败: {e}")
        else:
            print(f"预览文件不存在: {preview_paths}")

        # 从数据库中删除记录
        try:
            delete_record(record_id)
            print(f"成功删除数据库记录: {record_id}")
        except Exception as e:
            print(f"删除数据库记录失败: {e}")
            return jsonify({"success": False, "message": "删除数据库记录失败"})

        return jsonify({"success": True})
    except Exception as e:
        print(f"删除操作发生错误: {e}")
        return jsonify({"success": False, "message": str(e)})

scan_task = {
    'running': False,
    'thread': None,
    'stop_flag': False
}

@app.route("/scan", methods=['POST'])
def scan_videos():
    """启动扫描任务（异步）"""
    if scan_task['running']:
        return jsonify({"success": False, "message": "已有扫描任务在进行中"})
    def scan_job():
        scan_task['running'] = True
        scan_task['stop_flag'] = False
        try:
            processed_videos = set(get_all_processed_videos())
            new_videos_count = 0
            for root, _, files in os.walk(VIDEO_SOURCE_DIR):
                for file in files:
                    if scan_task['stop_flag']:
                        break
                    if file.lower().endswith((".mp4", ".mov", ".avi", ".mkv")):
                        video_path = os.path.join(root, file)
                        if video_path not in processed_videos:
                            preview_paths = process_video(video_path)
                            if preview_paths:
                                new_videos_count += 1
                if scan_task['stop_flag']:
                    break
            scan_task['running'] = False
        except Exception as e:
            scan_task['running'] = False
    t = threading.Thread(target=scan_job, daemon=True)
    scan_task['thread'] = t
    t.start()
    return jsonify({"success": True, "message": "扫描任务已启动"})

@app.route("/scan_status")
def scan_status():
    return jsonify({"running": scan_task['running']})

@app.route("/stop_scan", methods=['POST'])
def stop_scan():
    if scan_task['running']:
        scan_task['stop_flag'] = True
        return jsonify({"success": True, "message": "终止请求已发送"})
    else:
        return jsonify({"success": False, "message": "没有正在进行的扫描任务"})

def calculate_file_md5(file_path):
    """计算文件的MD5值"""
    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

@app.route("/favorite/<int:record_id>", methods=['POST'])
def toggle_favorite(record_id):
    """切换视频收藏状态"""
    try:
        record = get_record_by_id(record_id)
        if not record:
            return jsonify({"success": False, "message": "视频不存在"})

        # 获取视频文件路径
        video_path = record['original']
        if not os.path.exists(video_path):
            return jsonify({"success": False, "message": "视频文件不存在"})

        # 获取文件名和扩展名
        filename = os.path.basename(video_path)
        name, ext = os.path.splitext(filename)
        
        # 如果视频已经在收藏文件夹中，则移回原位置
        if os.path.exists(video_path) and os.path.dirname(video_path) == FAVORITE_DIR:
            # 从收藏文件夹移回原位置
            original_name = name[33:] if len(name) > 33 else name  # 移除MD5前缀
            target_path = os.path.join(VIDEO_SOURCE_DIR, original_name + ext)
            shutil.move(video_path, target_path)
            # 更新数据库中的文件路径
            update_record_path(record_id, target_path)
            update_record_favorite(record_id, False)
            return jsonify({"success": True, "is_favorite": False})
        else:
            # 计算MD5并移动到收藏文件夹
            file_md5 = calculate_file_md5(video_path)
            target_filename = f"{file_md5}_{filename}"
            target_path = os.path.join(FAVORITE_DIR, target_filename)
            shutil.move(video_path, target_path)
            # 更新数据库中的文件路径
            update_record_path(record_id, target_path)
            update_record_favorite(record_id, True)
            return jsonify({"success": True, "is_favorite": True})

    except Exception as e:
        return jsonify({"success": False, "message": str(e)})

def save_records(video_path, preview_paths):
    """保存视频处理记录到数据库"""
    db_save_records(video_path, preview_paths)

if __name__ == "__main__":
    # 初始化数据库和目录
    init_db()
    
    # 启动Web服务
    app.run(host="0.0.0.0", port=5000, debug=True)
    